import tempfile
from datetime import datetime

import pandas as pd
from django.core.mail import send_mail
from django.http import HttpResponse

# Create your views here.
from django.utils.dateparse import parse_datetime
from rest_framework import status
from rest_framework.parsers import MultiPartParser, FormParser
from rest_framework.permissions import BasePermission
from rest_framework.response import Response
from rest_framework.views import APIView
from CourseAdjustmentManagement.models import ClassroomSchedule, ClassroomSchedule
from CourseAdjustmentManagement.serializers import ClassroomScheduleSerializer, ClassroomScheduleSerializer
from CourseAdjustmentManagement.views.public_data import our_classroom
from CourseAdjustmentManagement.views.views import model_info_dict
from HopeIESystem.settings import DEFAULT_FROM_EMAIL
from UserManager.models import User


class IsReviewer(BasePermission):

    def has_permission(self, request, view):
        # 假设您有一个名为 'reviewer' 的用户组

        return request.user.groups.filter(name='reviewer').exists()


class IsTDAdmin(BasePermission):
    def has_permission(self, request, view):
        # 假设您有一个名为 'TDAdmin' 的用户组

        return request.user.groups.filter(name='TDAdmin').exists()


class IsTDAdminOrIsReviewer(BasePermission):
    def has_permission(self, request, view):
        # 检查用户是否是管理员或审核者
        return request.user.groups.filter(name='TDAdmin').exists() or request.user.groups.filter(
            name='reviewer').exists()


# 创建
class CreateView(APIView):
    # 定义一个Report字段为空对象
    permission_classes = [IsTDAdminOrIsReviewer]
    model = None
    Serializer = None

    def post(self, request):
        # 判断是否request.user.name ==request.data.name
        # 如果是，则继续处理POST请求
        # 返回所有TrainingReport满足 TrainingReport.objects.author[0]==request.user.name的条目
        # 如果不是，则返回错误信息
        try:
            # 获取字段从而知道操作哪个模型类与序列化类

            self.model = ClassroomSchedule
            self.Serializer = ClassroomScheduleSerializer
            return self.get_reports(request)
        except Exception as e:
            return Response({'error': 'Invalid data:' + str(e)}, status=status.HTTP_400_BAD_REQUEST)

    def get_reports(self, request):
        # 将request.data中的数据序列化后添加到model中。
        serializer = self.Serializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response({'success': '数据添加成功'}, status=201)
        else:
            return Response({'error': '无效数据: ' + str(serializer.errors)}, status=400)


# 利用上传的word创建
class CreateViewWord(APIView):
    parser_classes = [MultiPartParser, FormParser]
    permission_classes = [IsTDAdminOrIsReviewer]
    model = None
    Serializer = None

    def post(self, request):
        try:
            self.model = ClassroomSchedule
            self.Serializer = ClassroomScheduleSerializer
            return self.get_reports(request)
        except Exception as e:
            return Response({'error': 'Invalid data:' + str(e)}, status=400)

    def get_reports(self, request):
        datas = []
        file = request.FILES['file']
        df = pd.read_excel(file)
        weeks = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日']
        classroom_our = our_classroom
        term = self.infer_semester()
        self.model.objects.filter(term=term).delete()
        for index, row in df.iterrows():
            # 获取每一行的数据
            week_per = self.parse_week_range(row['上课周次'])
            for week_per_one in week_per:
                # 获取上课地点字符串
                # 利用 / 将classroom_now_str 其分为list
                classroom_now_str = row['上课地点']
                classroom_now_list = classroom_now_str.split('/')
                week_int = 0
                for week in weeks:
                    # week去除星期两个字
                    week_id = week[2:]

                    if pd.isna(row[week]):
                        continue
                    week_class_list = row[week].split('/')
                    for week_class in week_class_list:
                        new_class_time = str(week_id) + '/' + week_class
                        data_classroom = classroom_now_list[week_int]
                        for classroom_one in classroom_our:
                            if classroom_one in classroom_now_list[week_int]:
                                data_classroom = classroom_one
                                break
                        data = {
                            'classroom_name': data_classroom,
                            'course_id': row['课程号'],
                            'course_name': row['课程名'],
                            'new_class_time': new_class_time,
                            'teacher_id': row['教师号'],
                            'teacher_name': row['教师名'],
                            'term': term,
                            'week': week_per_one,
                        }
                        datas.append(data)
                        week_int += 1
                        if week_int >= len(classroom_now_list):
                            week_int = len(classroom_now_list) - 1

        try:
            serializer = self.Serializer(data=datas, many=True)
            if serializer.is_valid():
                serializer.save()
                return Response({'success': '批量数据添加成功'}, status=201)
            else:
                return Response({'error': '无效数据: ' + str(serializer.errors)}, status=400)

        except Exception as e:
            return Response({'error': '无效数据: ' + str(e)}, status=400)

    def parse_week_range(self, week_str):
        # 移除一个字符串中的 ‘周’
        week_str = week_str.replace('周', '')
        # 检查是否有连字符存在
        if '-' in week_str:
            start, end = map(int, week_str.split('-'))
            return list(range(start, end + 1))
        else:
            # 如果没有连字符，则返回单个元素的列表
            return [int(week_str)]

    # 根据当前时间推测学期
    def infer_semester(self):
        # 如果没有传入日期，默认使用当前日期
        current_date = datetime.now()

        month = current_date.month

        # 判断月份所属的学期
        if 2 <= month <= 7:
            # 当前处于春季学期
            year = current_date.year - 1
            semester = f"{year}-{current_date.year}学年春季学期"
        elif 8 <= month <= 12 or month == 1:
            # 当前处于秋季学期，注意1月属于上一学年的秋季学期
            year = current_date.year if month != 1 else current_date.year - 1
            semester = f"{year}-{year + 1}学年秋季学期"
        else:
            raise ValueError("Month value is out of range (1-12).")

        return semester

    # 数据校验


# 删除条目
class DeleteView(APIView):
    permission_classes = [IsTDAdminOrIsReviewer]
    model = None
    Serializer = None

    def post(self, request):
        # 判断是否request.user.name ==request.data.name
        # 如果是，则继续处理POST请求
        # 返回所有TrainingReport满足 TrainingReport.objects.author[0]==request.user.name的条目
        # 如果不是，则返回错误信息
        try:
            # 获取字段从而知道操作哪个模型类与序列化类
            self.model = ClassroomSchedule
            self.Serializer = ClassroomScheduleSerializer
            report = self.model.objects.get(id=request.data['id'])

            return self.get_reports(report)
        except Exception as e:
            return Response({'error': '无效数据:' + str(e)}, status=400)

    def get_reports(self, report):
        # 获取id，根据id删除该条目
        report.delete()
        return Response({'success': '数据已经删除'}, status=200)


# 清空整张表
class ClearView(APIView):
    permission_classes = [IsTDAdmin]
    model = None
    Serializer = None

    def post(self, request):
        # 判断是否request.user.name ==request.data.name
        # 如果是，则继续处理POST请求
        # 返回所有TrainingReport满足 TrainingReport.objects.author[0]==request.user.name的条目
        # 如果不是，则返回错误信息
        try:
            # 获取字段从而知道操作哪个模型类与序列化类
            self.model = ClassroomSchedule
            self.Serializer = ClassroomScheduleSerializer
            return self.get_reports(request)
        except Exception as e:
            return Response({'error': '无效数据:' + str(e)}, status=400)

    def get_reports(self, request):
        # 获取id，根据id删除该条目
        self.model.objects.all().delete()
        return Response({'success': '数据已经清空'}, status=200)


# 修改条目
class UpdateView(APIView):
    permission_classes = [IsTDAdminOrIsReviewer]
    model = None
    Serializer = None

    def post(self, request):
        # 判断是否request.user.name ==request.data.name
        # 如果是，则继续处理POST请求
        # 返回所有TrainingReport满足 TrainingReport.objects.author[0]==request.user.name的条目
        # 如果不是，则返回错误信息
        try:
            self.model = ClassroomSchedule
            self.Serializer = ClassroomScheduleSerializer
            report = self.model.objects.get(id=request.data['id'])

            return self.get_reports(request, report)
        except Exception as e:
            return Response({'error': '无效数据: ' + str(e)}, status=400)

    def get_reports(self, request, report):
        # 获取id，根据id修改该条目,用序列化

        serializer = self.Serializer(report, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response({'success': '管理员修改成功'}, status=200)
        else:
            return Response({'error': '提交了无效数据:' + str(serializer.errors)}, status=400)


# 获取所有条目
class GetAdminView(APIView):
    permission_classes = [IsTDAdminOrIsReviewer]
    model = None
    Serializer = None

    def post(self, request):
        # 判断是否request.user.name ==request.data.name
        # 如果是，则继续处理POST请求
        # 返回所有TrainingReport满足 TrainingReport.objects.author[0]==request.user.name的条目
        # 如果不是，则返回错误信息
        # try:
        try:
            self.model = ClassroomSchedule
            self.Serializer = ClassroomScheduleSerializer
            return self.get_reports(request)
        except Exception as e:
            return Response({'error': 'Invalid data:' + str(e)}, status=400)

    # except Exception as e:
    #     return Response({'error': 'Invalid data:' + str(e)}, status=400)

    def get_reports(self, request):
        # 根据id返回TrainingReport
        if not request.data['term'] or request.data['term'] == '':
            reports = self.model.objects.all()
        else:
            reports = self.filter_reports_by_term(request)

        serializer = self.Serializer(reports, many=True, context={'request': request})
        return Response(serializer.data, status=200)

    def filter_reports_by_term(self, request):
        term = request.data.get('term')
        reports = self.model.objects.filter(term=term)

        return reports


# 获取能用的教室
class GetView(APIView):
    model = None
    Serializer = None
    classroom = our_classroom

    def post(self, request):
        # 判断是否request.user.name ==request.data.name
        # 如果是，则继续处理POST请求
        # 返回所有TrainingReport满足 TrainingReport.objects.author[0]==request.user.name的条目
        # 如果不是，则返回错误信息
        # try:
        try:
            self.model = ClassroomSchedule
            self.Serializer = ClassroomScheduleSerializer
            return self.get_reports(request)
        except Exception as e:
            return Response({'error': 'Invalid data:' + str(e)}, status=400)

    # except Exception as e:
    #     return Response({'error': 'Invalid data:' + str(e)}, status=400)

    def get_reports(self, request):
        # 根据id返回TrainingReport
        reports = self.filter_reports(request)
        can_use_room = self.classroom
        # 获取这些reports的教室名
        for report in reports:
            if report.classroom_name in can_use_room:
                can_use_room.remove(report.classroom_name)

        return Response({'can_use_room': can_use_room}, status=200)

    def filter_reports(self, request):
        reports = self.model.objects.filter(term=request.data.get('term'))
        reports = reports.filter(week=request.data.get('week'))
        new_reports = []
        new_class_time = request.data.get('new_class_time')
        # 判断时间段是否冲突
        self_day, class_range_str = new_class_time.split('/')
        self_start_class, self_end_class = class_range_str.split('-')
        for report in reports:
            report_day, record_class_range_str = report.new_class_time.split('/')
            report_start_class, report_end_class = record_class_range_str.split('-')
            if self_day == report_day:
                if int(self_end_class) < int(report_start_class) or (int(self_start_class) > int(report_end_class)):
                    pass
                else:
                    new_reports.append(report)
        return new_reports

# 审批


# 下载excel
